package controller

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"ip_server/logger"
	"ip_server/service/model"
	"ip_server/service/param"
	"ip_server/util"
	"net/http"
	"net/url"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

type IndexController struct {
}

const (
	version                   = 1
	accessKeyId               = "ALTAKBTDjoSo1rqAtbMHSNxNb5"
	secretAccessKey           = "646bc4fdccd04fbb82ad89d8340cd297"
	expirationPeriodInSeconds = 1800 // 30 minutes
)

func generateSignature(secretKey string, stringToSign string) string {
	h := hmac.New(sha256.New, []byte(secretKey))
	h.Write([]byte(stringToSign))
	return hex.EncodeToString(h.Sum(nil))
}

func generateAuthString(httpMethod, path, queryString, host, timestamp string) string {
	//timestamp := time.Now().UTC().Format("2006-01-02T15:04:05Z")
	signedHeaders := "host;x-bce-date"

	authStringPrefix := fmt.Sprintf("bce-auth-v%d/%s/%s/%d", version, accessKeyId, timestamp, expirationPeriodInSeconds)
	fmt.Println("-------------------------------authStringPrefix:", authStringPrefix)
	SigningKey := generateSignature(secretAccessKey, authStringPrefix)
	fmt.Println("-------------------------------SigningKey:", SigningKey)

	canonicalHeaders := fmt.Sprintf("host:%s\nx-bce-date:%s", host, url.QueryEscape(timestamp))

	canonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s", httpMethod, path, queryString, canonicalHeaders)

	//stringToSign := fmt.Sprintf("bce-auth-v%d/%s/%s/%d/%s/%s", version, accessKeyId, url.QueryEscape(timestamp), expirationPeriodInSeconds, signedHeaders, canonicalRequest)
	signature := generateSignature(SigningKey, canonicalRequest)
	fmt.Println("-------------------------------signature:", signature)

	authString := fmt.Sprintf("bce-auth-v%d/%s/%s/%d/%s/%s", version, accessKeyId, timestamp, expirationPeriodInSeconds, signedHeaders, signature)
	return authString
}

// ChannelAntiCheat 渠道反作弊
func (idx *IndexController) ChannelAntiCheat(c *gin.Context) {
	logid := util.GenerateLogid() // 生成日志ID，用于追踪和记录该请求的日志

	var req param.ChannelAntiCheatReq
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error(logid, err)
		c.Set("res", gin.H{
			"status": 1,
			"msg":    err.Error(),
		})
		return
	}
	// 获取当前时间
	now := time.Now()
	// 将当前时间转换为毫秒级时间戳
	Ctstimestamp := now.UnixNano() / int64(time.Millisecond)
	req.CTs = fmt.Sprintf("%d", Ctstimestamp)
	postData, _ := json.Marshal(req)
	path := "/rcs/sync-saas"
	host := "afd.baidubce.com"
	url := fmt.Sprintf("https://%s%s", host, path)
	res, _ := http.NewRequest("POST", url, bytes.NewBuffer(postData))
	queryString := ""
	timestamp := time.Now().UTC().Format("2006-01-02T15:04:05Z")
	authString := generateAuthString("POST", path, queryString, host, timestamp)
	fmt.Println("-------------------------------Authorization:", authString)
	res.Header.Set("Authorization", authString)
	res.Header.Set("x-bce-date", timestamp)

	client := &http.Client{}
	resp, err := client.Do(res)
	if err != nil {
		logger.Error(logid, err)
		c.Set("res", gin.H{
			"status": 1,
			"msg":    err.Error(),
		})
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("Response status:", resp.Status)
	fmt.Println("Response body:", string(body))
	var baseResp param.BaseResponse
	err = json.Unmarshal(body, &baseResp)
	if err != nil {
		fmt.Println("Error unmarshaling response:", err)
		c.Set("err", err.Error())
		return
	}
	if baseResp.RetCode != "0" {
		c.Set("err", baseResp.RetMsg)
		return
	}

	var deviceResp param.ChannelCheatResponse
	err = json.Unmarshal(body, &deviceResp)
	if err != nil {
		fmt.Println("Error unmarshaling response:", err)
		c.Set("err", err.Error())
		return
	}

	c.Set("res", gin.H{
		"status":     0,
		"msg":        "success",
		"data":       deviceResp.RetData,
		"request_id": deviceResp.RequestID,
	})

}

// NewChannelAntiCheat 渠道反作弊
func (idx *IndexController) NewChannelAntiCheat(c *gin.Context) {
	logid := util.GenerateLogid() // 生成日志ID，用于追踪和记录该请求的日志

	var req param.NewChannelAntiCheatReq
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error(logid, err)
		c.Set("res", gin.H{
			"status": 1,
			"msg":    err.Error(),
		})
		return
	}
	postData, _ := json.Marshal(req)
	path := "/rcs/sync-saas"
	host := "afd.baidubce.com"
	url := fmt.Sprintf("https://%s%s", host, path)
	res, _ := http.NewRequest("POST", url, bytes.NewBuffer(postData))
	queryString := ""
	timestamp := time.Now().UTC().Format("2006-01-02T15:04:05Z")
	authString := generateAuthString("POST", path, queryString, host, timestamp)
	fmt.Println("-------------------------------Authorization:", authString)
	res.Header.Set("Authorization", authString)
	res.Header.Set("x-bce-date", timestamp)

	client := &http.Client{}
	resp, err := client.Do(res)
	if err != nil {
		logger.Error(logid, err)
		c.Set("res", gin.H{
			"status": 1,
			"msg":    err.Error(),
		})
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("Response status:", resp.Status)
	fmt.Println("Response body:", string(body))
	var baseResp param.BaseResponse
	err = json.Unmarshal(body, &baseResp)
	if err != nil {
		fmt.Println("Error unmarshaling response:", err)
		c.Set("err", err.Error())
		return
	}
	if baseResp.RetCode != "0" {
		c.Set("err", baseResp.RetMsg)
		return
	}

	var deviceResp param.ChannelCheatResponse
	err = json.Unmarshal(body, &deviceResp)
	if err != nil {
		fmt.Println("Error unmarshaling response:", err)
		c.Set("err", err.Error())
		return
	}

	c.Set("res", gin.H{
		"status":     0,
		"msg":        "success",
		"data":       deviceResp.RetData,
		"request_id": deviceResp.RequestID,
	})

}

// DeviceRiskCheck 设备风险查询
func (idx *IndexController) DeviceRiskCheck(c *gin.Context) {
	logid := util.GenerateLogid() // 生成日志ID，用于追踪和记录该请求的日志

	var req param.DeviceRiskReq
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error(logid, err)
		c.Set("res", gin.H{
			"status": 1,
			"msg":    err.Error(),
		})
		return
	}
	postData, _ := json.Marshal(req)
	path := "/rcs/factor-saas"
	host := "afd.baidubce.com"
	url := fmt.Sprintf("https://%s%s", host, path)
	res, _ := http.NewRequest("POST", url, bytes.NewBuffer(postData))
	queryString := ""
	timestamp := time.Now().UTC().Format("2006-01-02T15:04:05Z")
	authString := generateAuthString("POST", path, queryString, host, timestamp)
	fmt.Println("-------------------------------Authorization:", authString)
	res.Header.Set("Authorization", authString)
	res.Header.Set("x-bce-date", timestamp)

	client := &http.Client{}
	resp, err := client.Do(res)
	if err != nil {
		logger.Error(logid, err)
		c.Set("res", gin.H{
			"status": 1,
			"msg":    err.Error(),
		})
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("Response status:", resp.Status)
	fmt.Println("Response body:", string(body))
	var baseResp param.BaseResponse
	err = json.Unmarshal(body, &baseResp)
	if err != nil {
		fmt.Println("Error unmarshaling response:", err)
		c.Set("err", err.Error())
		return
	}
	if baseResp.RetCode != "0" {
		c.Set("err", baseResp.RetMsg)
		return
	}
	var deviceResp param.DeviceRiskResponse
	err = json.Unmarshal(body, &deviceResp)
	if err != nil {
		fmt.Println("Error unmarshaling response:", err)
		c.Set("err", err.Error())
		return
	}
	c.Set("res", gin.H{
		"status":     0,
		"msg":        "success",
		"data":       deviceResp.RetData,
		"request_id": deviceResp.RequestID,
	})

}



// LogList 组列表接口
func (grp *IndexController) LogList(c *gin.Context) {
	logid := util.GenerateLogid() // 生成日志ID，用于追踪和记录该请求的日志
	var page,pagesize int
	var err error
	if c.Query("page") != "" {
		page, err = strconv.Atoi(c.Query("page"))
		if err != nil {
			page = 1
		} else if page < 1 {
			page = 1
		}
	}
	if c.Query("page_size") != "" {
		pagesize, err = strconv.Atoi(c.Query("page_size"))
		if err != nil {
			pagesize = 10
		} else if page < 1 {
			pagesize = 10
		}
	}
	var pmodel model.Log
	total,glist, err := pmodel.List(param.LogsReqBefore{
		Page:page,
		PageSize:pagesize,
	})
	if err != nil {
		// 查询失败时，记录错误日志，并设置错误信息到上下文中
		logger.Error(logid, err.Error())
		c.Set("err", err.Error())
		return
	}
	c.Set("res", gin.H{
		"status": 0,
		"msg":    "success",
		"data":   map[string]interface{}{
			"list":glist,
			"page":page,
			"page_size":pagesize,
			"total":total,
		},
	})
}

// ConfigList 组列表接口
func (grp *IndexController) ConfigList(c *gin.Context) {
	logid := util.GenerateLogid() // 生成日志ID，用于追踪和记录该请求的日志
	var page,pagesize int
	var err error
	if c.Query("page") != "" {
		page, err = strconv.Atoi(c.Query("page"))
		if err != nil {
			page = 1
		} else if page < 1 {
			page = 1
		}
	}
	if c.Query("page_size") != "" {
		pagesize, err = strconv.Atoi(c.Query("page_size"))
		if err != nil {
			pagesize = 1
		} else if page < 1 {
			pagesize = 1
		}
	}
	var pmodel model.Config
	total,glist, err := pmodel.List(param.ConfigsReqBefore{
		Page:page,
		PageSize:pagesize,
	})
	if err != nil {
		// 查询失败时，记录错误日志，并设置错误信息到上下文中
		logger.Error(logid, err.Error())
		c.Set("err", err.Error())
		return
	}
	c.Set("res", gin.H{
		"status": 0,
		"msg":    "success",
		"data":   map[string]interface{}{
			"list":glist,
			"page":page,
			"page_size":pagesize,
			"total":total,
		},
	})
}

